//
// Created by Administrator on 2024/10/30.
//


#include "ArchiveHandler.h"
#include "../utils/ArchiveEnumUtils.h"


bool ArchiveHandler::handlePost(CivetServer *server, struct mg_connection *conn) {

    ArcNotice notice;
    notice.requestId = "";
    notice.status = 0;
    notice.message = "成功";
    try {
        Request request;
        request.read(conn);

        json j_complete = request.getData();
        auto req = j_complete.get<ArchiveReq>();
        notice.requestId = req.requestId;
        notice.studyUID = archive_dicom(req);
        JsonResponse response(notice);
        response.success(conn);
        return true;
    } catch (const std::exception &e) {
        notice.status = 1;
        notice.message = "失败";
        std::string err = std::string(e.what());
        JsonResponse response(json::object(), err);
        response.error(conn);
        LOG(err);
        return false;
    }
}


std::string ArchiveHandler::archive_dicom(ArchiveReq &req) {
    DicomArchive arc;
    arc.request_id = req.requestId;
    arc.task_status = static_cast<int>(ArchiveEnumStatus::Archiving);
    arc.remark = ArchiveEnumUtils::ToStringArchiveEnumStatus(ArchiveEnumStatus::Archiving);
    arc.is_notified = static_cast<int>(ArchiveEnumNotified::UNNotification);
    arc.modified_time = DateUtils::getCurrentDateString();

    try {
        create_archive_record(req);

        if (req.studyUID.empty() && req.files.empty()) {
            throw std::runtime_error("study_instance_uid和files参数不能都为空 ");
        }

        auto archive_needed = true;
        if (!req.studyUID.empty()) {
            archive_needed = verify_file_instance(req);
        }

        if (archive_needed && !req.files.empty()) {
            req.studyUID = archive_instances(req);
        }

        arc.study_instance_uid = req.studyUID;
        arc.task_status = static_cast<int>(ArchiveEnumStatus::ArchiveSuccess);
        arc.remark = ArchiveEnumUtils::ToStringArchiveEnumStatus(ArchiveEnumStatus::ArchiveSuccess);
        update_archive_record(arc);

        return req.studyUID;
    } catch (const std::exception &e) {
        arc.task_status = static_cast<int>(ArchiveEnumStatus::ArchiveFailed);
        arc.remark = ArchiveEnumUtils::ToStringArchiveEnumStatus(ArchiveEnumStatus::ArchiveFailed);
        update_archive_record(arc);
        throw std::runtime_error(e.what());
    }

}

void ArchiveHandler::create_archive_record(ArchiveReq &req) {
    ResourcesProcessor processor;
    auto res = processor.getList(req.requestId);
    if (!res.empty() && res[0].task_status == 2) {
        throw std::runtime_error("该request id 已经存在，并且正在执行 ");
    }
    if (res.empty()) {
        processor.create(req.requestId, req.hospCode, req.studyUID);
    }
}

bool ArchiveHandler::verify_file_instance(ArchiveReq &req) {
    FileInstanceProcessor processor;
    auto res = processor.getList(req.hospCode, req.studyUID);
    if (!res.empty()) {
        return false;
    }
    return true;
}

std::string ArchiveHandler::archive_instances(ArchiveReq &req) {

    std::string requestIdPtah = "../tmp/" + req.requestId;

    try {
        FilesOperator::create_directories(requestIdPtah);

        auto tmp_files = archive_download(req.files, req.fileType, requestIdPtah);

        auto studyImages = read_dicom_file(tmp_files, req.hospCode);

//        archive_upload(studyImages);

        auto study = aggregate_result(studyImages);

//        auto keyByPrefix = DcmToolKit::getObjKeyByPrefix(studyImages[0]);
//        send_app_json_object_storage(keyByPrefix, study);

        create_file_instance(study);

        FilesOperator::delete_tmp_files(requestIdPtah);

        return req.studyUID;

    } catch (const std::exception &e) {

        FilesOperator::delete_tmp_files(requestIdPtah);
        throw std::runtime_error(e.what());

    }
}

std::vector<std::string>
ArchiveHandler::archive_download(std::vector<std::string> &files, std::string &fileType, std::string &requestIdPtah) {
    return {
            "../tmp/f9144c7d-dd9e-4fb2-96eb-e354dc7dbb30/CT.1.2.840.113619.2.278.3.2831181064.561.1726441345.163.1.dcm",
            "../tmp/f9144c7d-dd9e-4fb2-96eb-e354dc7dbb30/CT.1.2.840.113619.2.278.3.2831181064.561.1726441345.163.2.dcm",
            "../tmp/f9144c7d-dd9e-4fb2-96eb-e354dc7dbb30/CT.1.2.840.113619.2.278.3.2831181064.561.1726441345.163.3.dcm",
            "../tmp/f9144c7d-dd9e-4fb2-96eb-e354dc7dbb30/CT.1.2.840.113619.2.278.3.2831181064.561.1726441345.163.4.dcm",
            "../tmp/f9144c7d-dd9e-4fb2-96eb-e354dc7dbb30/CT.1.2.840.113619.2.278.3.2831181064.561.1726441345.163.5.dcm",
    };

    std::vector<std::string> tmp_files;
    if (fileType == "zip") {
        std::string zip_file = std::format("{}/{}.zip", requestIdPtah, UuidGenerate::uuid37());
        Downloader::curlTask(*files.begin(), zip_file);
        tmp_files = CompressZip::decompressZip(zip_file.c_str(), requestIdPtah.c_str());
    }
    tmp_files = Downloader::Executor(files, requestIdPtah);

    return tmp_files;

}


std::vector<std::map<std::string, std::string>>
ArchiveHandler::read_dicom_file(std::vector<std::string> &files, std::string &hospCode) {
    return DcmToolKit::Executor(files, hospCode);

}

void ArchiveHandler::archive_upload(std::vector<std::map<std::string, std::string>> &images) {
    AwsS3Client::Executor(images);
}

DicomStudy ArchiveHandler::aggregate_result(std::vector<std::map<std::string, std::string>> &images) {
    return DicomImage::addSeriesToStudy(images);

}

void ArchiveHandler::send_app_json_object_storage(const std::string &prefix, const DicomStudy &study) {
    AwsS3Client client;
    client.UploadJsonToS3(std::format("{}/app.json", prefix), study);
}

void ArchiveHandler::create_file_instance(const DicomStudy &study) {
    FileInstanceProcessor processor;
    processor.create(study);
}

void ArchiveHandler::update_archive_record(const DicomArchive &arc) {
    ResourcesProcessor processor;
    processor.update(arc);
}






